#ifndef MOTIONCARD_P_H
#define MOTIONCARD_P_H
#include "motioncard.h"
#include <time.h>

template <typename Functor>
bool delay(Functor functor, const int millisec)
{
	clock_t goal;
	goal = millisec + clock();
	while( goal > clock() )
	{
		if (functor())
		{
			return true;
		}
		else
		{
			QCoreApplication::processEvents();
		}
	}
	return false;
}

void delay(const int millisec)
{
	clock_t goal;
	goal = millisec + clock();
	while( goal > clock() )
	{		
		QCoreApplication::processEvents();
	}
}

class MotorPrivate
{
public:
	MotorPrivate(const uint index, Motor* parent)
		: q_ptr(parent)
		, index(index)
		, initialVelocity(0.)
		, drivingVelocity(0.)
		, accelerationTime(0.)
		, initialPosition(0.)
		, gearRatio(0.)
		, timeout(0)		
	{

	}
protected:
	Motor* q_ptr;	
	Q_DECLARE_PUBLIC(Motor);
private:
	uint index;
	double initialVelocity;
	double drivingVelocity;
	double accelerationTime;
	double initialPosition;
	double gearRatio;
	uint timeout;
};


class MotionCardPrivate
{
public:
	MotionCardPrivate(MotionCard* parent)
		: q_ptr(parent)
	{

	}
public:
	bool waitForDone()
	{
		foreach(Motor* motor,motorMap.values())
		{
			if (!motor->checkDone())
			{
				return false;
			}
		}
		return true;
	}
protected:
	Q_DECLARE_PUBLIC(MotionCard);
	MotionCard* q_ptr;
private:
	uint availabel;
	uint inputWidth;
	uint outputWidth;
	typedef QMap<uint,Motor*> MotorMap;
	MotorMap motorMap;
};

class VirtualMotorPrivate : MotorPrivate
{
public:
	VirtualMotorPrivate(const uint index, VirtualMotor* parent)
		: MotorPrivate(index, parent)
		, position(0.)
		, status(Motor::NEL)
		, driving(false)
	{
	}
private:
	Q_DECLARE_PUBLIC(VirtualMotor);
	double position;
	Motor::MotorStatus status;
	bool driving;
};

class VirtualMotionCardPrivate : MotionCardPrivate
{
public:
	VirtualMotionCardPrivate(VirtualMotionCard* parent)
		: MotionCardPrivate(parent)		
	{
	}
private:
	Q_DECLARE_PUBLIC(VirtualMotionCard);
	QBitArray inputs;
	QBitArray outputs;
	
};
#endif